package com.ly.mp.dal.comm.config;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.alibaba.druid.pool.DruidDataSource;
import com.ly.mp.dal.comm.config.condition.TransactionPolicyGts;
import com.ly.mp.dal.comm.jdbc.DynamicDataSource;

import io.seata.rm.datasource.DataSourceProxy;
import io.seata.spring.annotation.GlobalTransactionScanner;

@Configuration
@Conditional({TransactionPolicyGts.class})
@EnableTransactionManagement(proxyTargetClass = true)
public class MpDataBaseGtsConfiguration {
    private static final Logger logger = LoggerFactory.getLogger(MpDataBaseGtsConfiguration.class);
    @Value("${seata.txgroup:my_test_tx_group}")
    private String txGroup;
    @Value("${seata.apolloAppId:seata-server}")
    private String appId;

    @Bean(name = {"dataSource"})
    public DataSource dynamicDataSource(BaseDataSourceInfo baseInfo, DatabaseSet dbSet) {
        Map<Object, Object> targetDataSources = new HashMap();
        DynamicDataSource dataSource = new DynamicDataSource();
        List<DataSourceInfo> infoList = dbSet.getDataSourceInfo();
        Iterator var6 = infoList.iterator();

        while (var6.hasNext()) {
            DataSourceInfo dbInfo = (DataSourceInfo) var6.next();
            DruidDataSource druidDataSource = new DruidDataSource();
            BeanUtils.copyProperties(baseInfo, druidDataSource);
            BeanUtils.copyProperties(dbInfo, druidDataSource);
            if (dbInfo.getUrl().contains("oracle")) {
                druidDataSource.setValidationQuery("select 1 from dual");
            } else {
                druidDataSource.setValidationQuery("select 1");
            }

            try {
                DataSourceProxy dsProxy = new DataSourceProxy(druidDataSource);
                druidDataSource.init();
                targetDataSources.put(dbInfo.getName() + "_writeDBKey", dsProxy);
            } catch (SQLException var10) {
                logger.error(var10.getMessage(), var10);
            }
        }

        dataSource.setDefaultTargetDataSource(targetDataSources.get(dbSet.getDefaultKey()));
        dataSource.setTargetDataSources(targetDataSources);
        return dataSource;
    }

    @Bean
    public GlobalTransactionScanner globalTransactionScanner(Environment environment) {
        String modelName = System.getProperty("service.name");
        String appName = Objects.isNull(modelName) ? "default" : modelName;
        String zkAddress = environment.getProperty("zookeeper.address");
        String sessionTime = environment.getProperty("zookeeper.session.timeout");
        String connectTime = environment.getProperty("zookeeper.connect.timeout");
        if (zkAddress != null && zkAddress.trim().length() > 0) {
            System.setProperty("zkAddress", zkAddress);
            System.setProperty("gtsRegistryType", "zk");
        } else {
            System.setProperty("zkAddress", "");
        }

        if (sessionTime != null) {
            System.setProperty("sessionTime", sessionTime);
        } else {
            System.setProperty("sessionTime", "");
        }

        if (connectTime != null) {
            System.setProperty("connectTime", connectTime);
        } else {
            System.setProperty("connectTime", "");
        }

        String eurekaServiceUrl = environment.getProperty("eureka.client.service-url.defaultZone");
        if (eurekaServiceUrl != null && eurekaServiceUrl.trim().length() > 0) {
            System.setProperty("eurekaServiceUrl", eurekaServiceUrl);
            System.setProperty("gtsRegistryType", "eureka");
        } else {
            System.setProperty("eurekaServiceUrl", "");
        }

        String nacosServerAddr = environment.getProperty("spring.cloud.nacos.discovery.server-addr");
        if (nacosServerAddr != null && nacosServerAddr.trim().length() > 0) {
            System.setProperty("nacosServerAddr", nacosServerAddr);
            System.setProperty("gtsRegistryType", "nacos");
        } else {
            System.setProperty("nacosServerAddr", "");
        }

        GlobalTransactionScanner globalTransactionScanner = new GlobalTransactionScanner(appName, this.txGroup);
        return globalTransactionScanner;
    }

    @Bean
    public PlatformTransactionManager transactionManager(DynamicDataSource dataSource) {
        DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
        transactionManager.setDataSource(dataSource);
        return transactionManager;
    }
}